<template>
  <div class="echarts-flying-line">
    <!-- 中国地图 -->
    <div id="chinaMap" ref="chinaDOM" :class="{ show: options?.map === 'china' }"></div>
    <!-- 世界地图 -->
    <div id="worldMap" ref="worldDOM" :class="{ show: options?.map === 'world' }"></div>
  </div>
</template>

<script>
import * as echarts from "echarts";
import "echarts-gl";
import customMap from "./map.png";
import ChinaJson from "./china.json";
import worldJson from "./world.json";
export default {
  props: {
    options: {
      type: Object,
      default: () => {},
    },
  },
  watch: {
    options: {
      handler() {
        this.init();
      },
      deep: true,
    },
  },
  data() {
    return {
      chinaChart: null,
      worldChart: null,
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      if (this.options?.map === "china") {
        this.initChinaMap();
      }
      if (this.options?.map === "world") {
        this.initWorldMap();
      }
    },
    /**
     * 初始化中国地图
     */
    initChinaMap() {
      if (this.chinaChart) {
        this.chinaChart.setOption(this.chinaChartOption(), true);
      } else {
        echarts.registerMap("china", ChinaJson);
        this.chinaChart = echarts.init(this.$refs["chinaDOM"]);
        this.chinaChart.setOption(this.chinaChartOption(), true);
        window.addEventListener("resize", () => {
          this.chinaChart.resize();
        });
      }
    },
    /**
     * 中国地图配置
     */
    chinaChartOption() {
      let data = {
        from: [{ name: "成都", value: [104.08347, 30.657689, 10] }],
        to: [
          { name: "上海", value: [121.4737, 31.2304, 2] },
          { name: "北京", value: [116.4074, 39.9042, 2] },
          { name: "武汉", value: [114.298572, 30.584355, 2] },
          { name: "广州", value: [113.2647, 23.1117, 2] },
          { name: "香港", value: [114.16, 22.28, 2] },
        ],
        lines: [
          {
            fromName: "成都",
            toName: "上海",
            coords: [
              [104.08347, 30.657689],
              [121.4737, 31.2304],
            ],
          },
          {
            fromName: "成都",
            toName: "北京",
            coords: [
              [104.08347, 30.657689],
              [116.4074, 39.9042],
            ],
          },
          {
            fromName: "成都",
            toName: "武汉",
            coords: [
              [104.08347, 30.657689],
              [114.298572, 30.584355],
            ],
          },
          {
            fromName: "成都",
            toName: "广州",
            coords: [
              [104.08347, 30.657689],
              [113.2647, 23.1117],
            ],
          },
          {
            fromName: "成都",
            toName: "香港",
            coords: [
              [104.08347, 30.657689],
              [114.16, 22.28],
            ],
          },
        ],
      };
      data = { ...data, ...this.options };
      // 定义所有系列
      let series = [
        // 起点
        {
          name: "起点",
          type: "scatter",
          coordinateSystem: "geo",
          zlevel: 999999999,
          rippleEffect: {
            period: 1,
            brushType: "stroke",
            scale: 8,
          },
          color: "rgba(148, 153, 50, 1)",
          label: {
            show: true,
            position: "top left",
            offset: [-30, -20],
            formatter: (params) => {
              return params.data.name;
            },
            color: "#fff",
            fontSize: 14,
            padding: [5, 8],
            backgroundColor: "rgba(148, 153, 50, 1)",
            borderRadius: 4,
            borderWidth: 1,
            borderType: "solid",
            borderColor: "#fff",
            emphasis: {
              show: true,
            },
          },
          labelLine: {
            show: true,
          },
          data: data.from,
        },
        // 终点
        {
          name: "终点",
          type: "effectScatter",
          coordinateSystem: "geo",
          zlevel: 9999999999999,
          rippleEffect: {
            color: "#91f8b4",
            brushType: "stroke",
            number: 3,
            scale: 5,
            period: 4,
          },
          symbol: "circle",
          symbolSize: 8,
          large: true,
          label: {
            show: true,
            position: "bottom left",
            offset: [15, 10],
            formatter: (params) => {
              // 根据name判断显示文本
              return params.data.name;
            },
            color: "#fff",
            fontSize: 14,
            padding: [5, 8],
            backgroundColor: "rgba(26, 160, 165, 1)",
            borderRadius: 4,
            borderWidth: 1,
            borderType: "solid",
            borderColor: "#fff",
          },
          emphasis: {
            show: true,
            scale: !0,
            label: {
              show: true,
              backgroundColor: "#000",
              padding: 2,
              borderRadius: 2,
              color: "#fff",
            },
          },
          itemStyle: {
            normal: {
              show: false,
              color: "#0FD1D9",
            },
          },
          data: data.to,
        },
        // 飞线
        {
          name: "飞线",
          type: "lines",
          coordinateSystem: "geo",
          zlevel: 200,
          large: true,
          animationDuration: 1000, //飞线动画的时长
          effect: {
            show: true,
            period: 2, //特效动画的时间，单位为 s。
            trailLength: 0.2, //特效尾迹长度[0,1]值越大，尾迹越长重
            symbol: "arrow", //箭头图标
            symbolSize: 6, //图标大小
            loop: true, // 是否循环播放
            roundTrip: false, // 是否是往返动画
          },
          lineStyle: {
            normal: {
              color: "#0FD1D9",
              width: 2,
              opacity: 0.6,
              curveness: 0.3,
            },
          },
          label: {
            normal: {
              show: false,
              position: "middle",
              formatter: "{b}",
            },
          },
          data: data.lines,
          show: true,
        },
      ];
      let option = {
        geo: [
          {
            map: "china",
            zoom: 1.1,
            zlevel: 10,
            label: {
              show: false,
              color: "#ffffff",
              fontSize: 14,
            },
            roam: false,
            itemStyle: {
              areaColor: {
                type: "pattern",
                image: customMap,
                repeat: "repeat",
              },
              borderWidth: 1,
              borderColor: "#89DAF7",
              shadowColor: "#03365b",
            },
            emphasis: {
              disabled: true,
              label: {
                show: false,
                color: "#ffffff",
              },
              itemStyle: {
                areaColor: {
                  type: "pattern",
                  image: customMap,
                  repeat: "repeat",
                },
              },
            },
          },
        ],
        series: series,
      };
      return option;
    },
    /**
     * 初始化世界地图
     */
    initWorldMap() {
      if (this.worldChart) {
        this.worldChart.setOption(this.worldChartOption(), true);
      } else {
        echarts.registerMap("world", worldJson);
        this.worldChart = echarts.init(this.$refs["worldDOM"]);
        this.worldChart.setOption(this.worldChartOption(), true);
        window.addEventListener("resize", () => {
          this.worldChart.resize();
        });
      }
    },
    /**
     * 世界地图配置
     */
    worldChartOption() {
      let data = {
        from: [{ name: "香港", value: [114.109497, 22.396428, 10] }],
        to: [
          {
            name: "河内",
            value: [105.85, 21.03, 2],
          },
          {
            name: "曼谷",
            value: [100.52, 13.75, 2],
          },
          {
            name: "吉隆坡",
            value: [101.687, 3.13829, 2],
          },
          {
            name: "雅加达",
            value: [106.8, 6.1667, 2],
          },
          {
            name: "马尼拉",
            value: [120.58, 14.35, 2],
          },
          {
            name: "利雅得",
            value: [46.71, 24.65, 2],
          },
          {
            name: "阿拉木图",
            value: [76.8428, 43.3267, 2],
          },
          {
            name: "塔什干",
            value: [69.2725, 41.4942, 2],
          },
          {
            name: "内罗毕",
            value: [36.49, 1.17, 2],
          },
          {
            name: "拉各斯",
            value: [3.4042, 6.4617, 2],
          },
          {
            name: "开罗",
            value: [31.5511, 30.0231, 2],
          },
        ],
        lines: [
          {
            fromName: "成都",
            toName: "河内",
            coords: [
              [114.109497, 22.396428],
              [105.85, 21.03],
            ],
          },
          {
            fromName: "成都",
            toName: "曼谷",
            coords: [
              [114.109497, 22.396428],
              [100.52, 13.75],
            ],
          },
          {
            fromName: "成都",
            toName: "吉隆坡",
            coords: [
              [114.109497, 22.396428],
              [101.687, 3.13829],
            ],
          },
          {
            fromName: "成都",
            toName: "雅加达",
            coords: [
              [114.109497, 22.396428],
              [106.8, 6.1667],
            ],
          },
          {
            fromName: "成都",
            toName: "马尼拉",
            coords: [
              [114.109497, 22.396428],
              [120.58, 14.35],
            ],
          },
          {
            fromName: "成都",
            toName: "利雅得",
            coords: [
              [114.109497, 22.396428],
              [46.71, 24.65],
            ],
          },
          {
            fromName: "成都",
            toName: "阿拉木图",
            coords: [
              [114.109497, 22.396428],
              [76.8428, 43.3267],
            ],
          },
          {
            fromName: "成都",
            toName: "塔什干",
            coords: [
              [114.109497, 22.396428],
              [69.2725, 41.4942],
            ],
          },
          {
            fromName: "成都",
            toName: "内罗毕",
            coords: [
              [114.109497, 22.396428],
              [36.49, 1.17],
            ],
          },
          {
            fromName: "成都",
            toName: "拉各斯",
            coords: [
              [114.109497, 22.396428],
              [3.4042, 6.4617],
            ],
          },
          {
            fromName: "成都",
            toName: "开罗",
            coords: [
              [114.109497, 22.396428],
              [31.5511, 30.0231],
            ],
          },
        ],
      };
      data = { ...data, ...this.options };
      let option = {
        // 提示框组件
        tooltip: {
          trigger: "item",
          formatter: function (params, ticket, callback) {
            if (params.seriesType == "effectScatter") {
              return params.marker + params.data.name + "" + params.data.value[2];
            } else if (params.seriesType == "lines") {
              return params.data.fromName + " -> " + params.data.toName + "<br />" + params.data.value;
            } else {
              return params.name;
            }
          },
        },
        grid: {
          right: "8%",
          // top:'5%'
        },
        // 视觉映射组件
        visualMap: [
          {
            show: false,
            seriesIndex: 0,
            dimension: 0, //取第一维度,批次
            right: 10,
            bottom: 10,
            zlevel: 10,
            calculable: true,
            min: 0,
            max: 10,
            inRange: {
              //由低到高
              color: ["#11eb11", "#006edd"],
            },
            textStyle: {
              color: "#fff",
              fontSize: 14,
            },
          },
        ],
        // 地理坐标系组件
        geo: {
          map: "world",
          // 保持比例，避免地图变形
          aspectScale: 0.75, // 高宽比
          zoom: 1.2,
          // zlevel: 20,//不行
          scaleLimit: {
            min: 1,
            max: 5,
          },
          label: {
            show: false,
          },
          roam: false, //缩放漫游
          // itemStyle: {
          //   normal: {
          //     shadowColor: "#4B6695",
          //     shadowOffsetX: 5,
          //     shadowOffsetY: 5,
          //   },
          // },
          itemStyle: {
            normal: {
              borderColor: "#3EC3E3",
              // 国家边界线的宽度
              borderWidth: 1,
              areaColor: "#4F6A99",
            },
            emphasis: {
              label: {
                // show: !1,
                color: "#fff",
              },
              // #0E83B7
              areaColor: "#4B6695",
              //    shadowColor: 'rgb(12,25,50)',
              borderWidth: 0.2,
            },
          },
          // 中国地图进行特殊样式处理
          regions: [
            {
              name: "china", // 国家名称（必须与地图数据匹配）
              itemStyle: {
                areaColor: {
                  type: "pattern",
                  image: customMap,
                  repeat: "repeat",
                },
                borderWidth: 1,
                borderColor: "#89DAF7",
                shadowColor: "#03365b",
              },
              label: {
                show: true, // 显示标签
                color: "#FFFFFF", // 标签颜色
                fontSize: 12,
              },
              emphasis: {
                // 悬停样式
                itemStyle: {
                  areaColor: "#FF6600",
                },
                label: {
                  color: "#000",
                },
              },
            },
          ],
        },
        series: [
          {
            name: "起点",
            type: "scatter",
            coordinateSystem: "geo",
            zlevel: 99999,
            rippleEffect: {
              period: 1,
              brushType: "stroke",
              scale: 8,
            },
            color: "rgba(148, 153, 50, 1)",
            label: {
              show: true,
              position: "top left",
              offset: [-30, -20],
              formatter: (params) => {
                return params.data.name;
              },
              color: "#fff",
              fontSize: 14,
              padding: [5, 8],
              backgroundColor: "rgba(148, 153, 50, 1)",
              borderRadius: 4,
              borderWidth: 1,
              borderType: "solid",
              borderColor: "#fff",
              emphasis: {
                show: true,
              },
            },
            labelLine: {
              show: true,
            },
            data: data.from,
          },
          // 动效散点图
          {
            name: "终点",
            type: "effectScatter",
            coordinateSystem: "geo",
            zlevel: 9999999999999,
            rippleEffect: {
              color: "#91f8b4", //涟漪的颜色，默认为散点的颜色
              brushType: "stroke", //波纹的绘制方式，可选 'stroke' 和 'fill'
              number: 3, //波纹的数量，默认是 3
              scale: 5, // 动画中波纹的最大缩放比例，默认为2.5
              period: 4, // 动画时间，秒数，默认为4
            },
            symbol: "circle",
            symbolSize: 8,
            large: true,
            label: {
              show: true,
              position: "bottom left", //显示位置
              offset: [15, 10], //偏移设置
              formatter: (params) => {
                return params.data.name;
              },
              color: "#fff",
              fontSize: 14,
              padding: [10, 8],
              // 调整标签背景
              backgroundColor: "rgba(0,83,161,0.8)",
              padding: [5, 8],
              borderRadius: 4,
              borderWidth: 1,
              borderType: "solid",
              borderColor: "#fff",
            },
            emphasis: {
              show: true,
              scale: !0,
              label: {
                show: true,
                backgroundColor: "#000",
                padding: 2,
                borderRadius: 2,
                color: "#fff",
              },
            },

            itemStyle: {
              normal: {
                show: false,
                color: "#0FD1D9",
              },
            },
            data: data.to,
          },
          // 飞线
          {
            name: "飞线",
            type: "lines",
            coordinateSystem: "geo",
            zlevel: 200,
            large: true,
            animationDuration: 1000, //飞线动画的时长
            effect: {
              show: true,
              period: 2, //特效动画的时间，单位为 s。
              trailLength: 0.2, //特效尾迹长度[0,1]值越大，尾迹越长重
              symbol: "arrow", //箭头图标
              symbolSize: 6, //图标大小
              loop: true, // 是否循环播放
              roundTrip: false, // 是否是往返动画
            },
            lineStyle: {
              normal: {
                color: "#0FD1D9",
                // 线条宽度
                width: 2,
                opacity: 0.6,
                curveness: 0.3,
              },
            },
            label: {
              normal: {
                show: false,
                position: "middle",
                formatter: "{b}",
              },
            },
            data: data.lines,
          },
        ],
      };
      return option;
    },
  },
};
</script>

<style lang="scss" scoped>
.echarts-flying-line {
  > div {
    width: 100%;
    height: 100%;
    z-index: 11;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    transition: all 0.5s ease-in-out;
    &:not(.show) {
      opacity: 0;
    }
    &.show {
      opacity: 1;
    }
  }
}
</style>
